#!/usr/bin/env python
# -*- coding: utf-8 -*-

from PyQt4.QtCore       import *
from PyQt4.QtGui        import *
from customevents       import *
from lyricenginsogou    import LyricEngineSogou
from lrcparser          import LrcParser

import commands
import time
import os

def guess_artist_and_title(media):
    """
    """
    media = os.path.basename(media)
    pos = media.find("-")
    if pos > 0:
        artist = media[:pos].strip()
        # remove the suffix
        title = media[pos + 1:].split(".")[0]
        pos = title.find("-")
        if pos > 0:
            pos = title[:pos].strip()
        if len(artist) > 0 and len(title) > 0:
            return (artist, title)

class AmarokCmt(QThread):
    """
    """

    def __init__(self, receiver):
        """
        """
        QThread.__init__(self)

        self.status = 'stop'
        self.title  = ""
        self.artist = ""
        self.media  = ""
        self.time   = 0

        # last values
        # to compare changed
        self.last_status = "stop"
        self.last_title  = ""
        self.last_artist = ""
        self.last_media  = ""
        self.last_time   = 0

        self.receiver = receiver

        self.lyric_engine = LyricEngineSogou()
        self.lrc_parser   = LrcParser()

        self._get_create_default_lrc_dir()

        print "default lrc directory is %s." % self.lrc_path

    def _get_create_default_lrc_dir(self):
        """
        
        Arguments:
        - `self`:
        """
        home = os.getenv("HOME")
        if home is None:
            home = "."
        self.lrc_path = home + "/lrc"

        if not os.path.isdir(self.lrc_path):
            os.mkdir(self.lrc_path)

    def _check_status(self):
        """
        
        Arguments:
        - `self`:
        """
        r = commands.getoutput('dcop amarok player status')

        if r == '2':
            self.status = 'playing'
        elif r == '0':
            self.status = 'stop'
        elif r == '1':
            self.status = 'pause'
        else:
            self.status = 'exit'

        if self.last_status != self.status:
            self.last_status = self.status
            event = StatusChangeEvent(self.status)
            QApplication.postEvent(self.receiver, event)

    def is_playing(self):
        """
        
        Arguments:
        - `self`:
        """
        return self.status == 'playing'

    def _parse_lrc_and_setup(self, lrc_text):
        """
        
        Arguments:
        - `self`:
        - `lrc_text`:
        """
        self.lrc_parser.set_text(lrc_text)
        self.lrc_parser.parse()
        lyrics = self.lrc_parser.result

        event = LyricChangeEvent(lyrics, self.artist, self.title)
        QApplication.postEvent(self.receiver, event)

    def _get_info(self):
        """
        
        Arguments:
        - `self`:
        """
        self.title  = commands.getoutput('dcop amarok player title')
        self.artist = commands.getoutput('dcop amarok player artist')
        self.media  = commands.getoutput('dcop amarok player path')

        if (not self.artist) or (not self.title):
            x, y = guess_artist_and_title(self.media)
            if x and y:
                self.artist = x
                self.title  = y

        if not (self.last_title == self.title
                and self.last_artist == self.artist):
            # download the lyric, and post to viewer
            self.last_title  = self.title
            self.last_artist = self.artist

            print "changing lyric to (%s - %s)..." % (self.artist, self.title)

            # get the lrc from net or file system
            lrc_fn = self.lrc_path + "/" + os.path.basename(self.media).split(".")[0] + ".lrc"

            if os.path.isfile(lrc_fn):
                print "used the lrc file saved in file system..."
                fp = open(lrc_fn)
                lrc_text = fp.read()
                fp.close()
                self._parse_lrc_and_setup(lrc_text)
            else:
                if not (len(self.artist) > 0 and len(self.title) > 0):
                    x, y = guess_artist_and_title(self.media)
                    if x is not None:
                        print "used the artist %s, title %s in media" % (x, y)
                        self.artist = x
                        self.title  = y

                if len(self.artist) > 0 and len(self.title) > 0:
                    print "searching from the net with keyword (%s - %s)..." \
                          % (self.artist, self.title)
                    urls = self.lyric_engine.request_lyric(self.artist,
                                                           self.title)
                    if len(urls) > 0:
                        print "found urls"
                        for url in urls:
                            print url
                        print "used the first one"
                        lrc_text = self.lyric_engine.download_lrc(urls[0])
                        if len(lrc_text) == 0:
                            print "download failed"
                        else:
                            self._parse_lrc_and_setup(lrc_text)

                            print "saving the lrc data to file %s..." % lrc_fn
                            fp = open(lrc_fn, "w")
                            fp.write(lrc_text)
                            fp.close()
                            return True
                print "not found lyric!"
                self._parse_lrc_and_setup("")

    def run(self):
        """
        
        Arguments:
        - `self`:
        """
        last_check_status_time = 0
        last_check_info_time   = 0
        while True:
            now = time.time()

            if now - last_check_status_time >= 0.1:
                self._check_status()
                last_check_status_time = now

            if self.is_playing() and now - last_check_info_time:
                self._get_info()
                last_check_info_time = now

            if self.is_playing():
                try:
                    self.time = int(commands.getoutput('dcop amarok player trackCurrentTimeMs'))
                except:
                    self.time = 0

                event = TimeChangeEvent(self.time)
                QApplication.postEvent(self.receiver, event)

            time.sleep(0.01)

class _Viewer(QGraphicsView):
    def __init__(self, scene, cmt):
        """
        
        Arguments:
        - `self`:
        """
        QGraphicsView.__init__(self, scene)

        self.cmt = cmt
        self.timer = QTimer()
        self.connect(self.timer, SIGNAL("timeout()"),
                     self._timeout)
        self.timer.start(1000)

        cmt.start()

    def _timeout(self):
        """
        
        Arguments:
        - `self`:
        """
        cmt = self.cmt
        print "status %s, title %s, artist %s, media %s, time %d" % (cmt.status,
                                                                     cmt.title,
                                                                     cmt.artist,
                                                                     cmt.media,
                                                                     cmt.time)

if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    scene = QGraphicsScene()
    scene.addText("hello kitty")
    view = _Viewer(scene, AmarokCmt())
    view.show()
    sys.exit(app.exec_())

